<?php

namespace app\system\controller;

use app\common\model\AdminModel;
use app\common\model\live\RoomModel;
use helper\Auth;
use helper\JwtHandler;
use traits\controller\JumpTraits;
use traits\controller\ListTraits;
use traits\controller\ViewTraits;
use think\facade\Cookie;

/**
 * 控制器基础类
 */
abstract class BaseController
{

  use JumpTraits;
  use ListTraits;
  use ViewTraits;

  /**
   * Request实例
   * @var \think\Request
   */
  protected $request;

  /**
   * 应用实例
   * @var \think\App
   */
  protected $app;

  /**
   * 控制器中间件
   * @var array
   */
  protected $middleware = [];

  /**
   * 权限实例
   * @var Auth|null
   */
  protected $auth = null;

  /**
   * 登录信息
   * @var array
   */
  protected $loginInfo = [];

  /**
   * 不需要登陆的方法
   * @var array
   */
  protected $noLogin = [];

  /**
   * 不检测权限方法
   * @var array
   */
  protected $noCheck = [];

  /**
   * 权限映射
   * @var array
   */
  protected $mapCheck = [];

  /**
   * 构造方法
   * @access public
   */
  public function __construct()
  {
    $this->app       = app();
    $this->request   = $this->app->request;
    $this->auth      = Auth::instance();
    $this->loginInfo = $this->checkLogin();
    if ($this->checkPermission() === false) {
      if ($this->request->isAjax()) {
        $this->error('您没有权限访问');
      } else {
        abort(500, '你没有权限访问！');
      }
    }
    $this->assign('loginInfo', $this->loginInfo);
    $this->assign('auth', $this->auth);
  }

  /**
   * 检测登录
   * @return array
   */
  protected function checkLogin()
  {
    $loginInfo = [];
    $action    = $this->request->action();
    if (in_array($action, $this->noLogin) || in_array('*', $this->noLogin)) {
      return $loginInfo;
    } else {
      try {
        $time   = time();
        $secret = config('auth.secret');
        $token  = Cookie::get('system_token');
        if (empty($token)) $this->redirect('public/login');
        $loginInfo = JwtHandler::decode($token, $secret);
        if (($loginInfo['exp'] - $time) < 600) { //续期token
          $loginInfo['exp'] = $time + 7200;
          $token            = JwtHandler::encode($loginInfo, $secret);
          Cookie::forever('system_token', $token);
        }
      } catch (\Throwable $th) {
        Cookie::delete('system_token');
        $this->redirect('public/login');
      }
    }
    return $loginInfo;
  }

  /**
   * 检测权限
   * @param null $name
   * @return bool
   */
  protected function checkPermission($name = null)
  {
    $action = $this->request->action();
    if (in_array($action, $this->noLogin) || in_array('*', $this->noLogin)) return true;
    if (in_array($this->loginInfo['uid'], config('auth.administrator'))) return true;
    if (in_array($action, $this->noCheck) || in_array('*', $this->noCheck)) return true;
    //检测权限
    if(empty($name)){
      $url = $this->request->url();
      $parseUrl = parse_url($url);
      $path     = explode('/', substr($parseUrl['path'], 1));
      $path[2]  = str_replace('.html', '', $path[2]); //action去除html后缀
      $url = $parseUrl['path'];
      if (isset($this->mapCheck['*'])) $url = $this->parseMapPath('*', $path);
      if (isset($this->mapCheck[$action])) $url = $this->parseMapPath($action, $path);
      $name = $url;
    }
    return $this->auth->check($name, $this->loginInfo['uid']);
  }

  /**
   * 获取path解析后路径
   * @param $key
   * @param $path
   * @return mixed
   */
  private function parseMapPath($key, $path)
  {
    if (isset($this->mapCheck[$key])) {
      $arr = explode('/', $this->mapCheck[$key]);
      if (count($arr) == 1) {
        $path[2] = $arr[0];
        $query   = '';
      } else if (count($arr) == 2) {
        $path[1] = $arr[0];
        $path[2] = $arr[1];
        $query   = '';
      } else if (count($arr) == 3) {
        $path[0] = $arr[0];
        $path[1] = $arr[1];
        $path[2] = $arr[2];
        $query   = '';
      }
    }
    return '/' . implode('/', $path) . '.html';
  }

  /**
   * 获取用户权限
   * @param string $field
   * @return array
   */
  public function getUidQuery($field = 'uid'){
    $query = [];
    if($this->loginInfo['account_type']==2){ //总账号
      $uids = AdminModel::where('pid',$this->loginInfo['uid'])->column('id');
      $uids[] = $this->loginInfo['uid'];
      $query[] = [$field,'in',$uids];
    }
    if($this->loginInfo['account_type']==3){ //子账号
      $query[] = [$field,'=',$this->loginInfo['uid']];
    }
    return $query;
  }

}
